<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Process Flow</title>
    <meta name="description" content="A simple process flow or SCADA diagram editor, simulating equipment monitoring and control." />
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js" ></script>
    <script src="../release/go.js"></script>
    <style>
        html,body{padding:0;margin:0;height:100%;}
        #sample{height:100%;position:relative;}
        #sample .buttonGroup{min-width: 180px;padding:10px;position:absolute;top:0;left:0;z-index:11;}
        #sample .toolGroup{padding:10px;position:absolute;top:100px;left:0;z-index:11;}
        #sample .toolGroup button{width:50px;min-width:inherit;}

        .mask{width:100%;height:100%;position:absolute;top:0;left:0;z-index:100;background-color:rgba(1,1,1,.3)}
        .mask img{width: 100px;height: 100px;margin: 100px auto;display: block;}
        .mask.hidden{display:none;}

        /** Base Spec */
        .v-btn {
            align-items: center;border-radius: 2px;display: inline-flex;height: 36px;flex: 0 0 auto;font-size: 14px;font-weight: 500;justify-content: center;margin: 6px 8px;min-width: 88px;
            outline: 0; text-transform: uppercase;text-decoration: none;transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), color 1ms; position: relative;vertical-align: middle;user-select: none;}
        .v-btn:hover {box-shadow: 1px 1px 2px rgba(1,1,1,.3);}
        .v-btn {padding: 0 16px;cursor:pointer;}
        .success {background-color: #4caf50 !important;  border-color: #4caf50 !important;color: #fff;letter-spacing:5px;}
    </style>
</head>
<body >
<div id="sample">
    <div class="mask hidden">
        <img src="./json/loading.gif" />
    </div>
    <div class="buttonGroup">
        <button class="v-btn success" data-index="save">保存</button>
    </div>
    <div class="toolGroup">
        <button class="v-btn" data-index="big">+</button>
        <br/>
        <button class="v-btn" data-index="small">-</button>
    </div>
    <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:100%"></div>
</div>
<script id="code">
    function init(layout) {
        var $$ = go.GraphObject.make;  // for more concise visual tree definitions
        var config = {
            allowDrop : true,
            "grid.visible": true,
            "grid.gridCellSize": new go.Size(30, 20),
            "draggingTool.isGridSnapEnabled": true,
            "rotatingTool.snapAngleMultiple": 90,
            "rotatingTool.snapAngleEpsilon": 45,
            "animationManager.isEnabled": false,
            "undoManager.isEnabled": false,
            "allowZoom":true,
            "scale":.7,
            "initialContentAlignment": go.Spot.Center
        }
        layout || (config.layout = $$(go.TreeLayout, { angle: 0, layerSpacing: 50 }))
        myDiagram = $$(go.Diagram, "myDiagramDiv",config);
        // when the document is modified, add a "*" to the title and enable the "Save" button
        myDiagram.addDiagramListener("Modified", function(e) {
            var button = document.getElementById("SaveButton");
            if (button) button.disabled = !myDiagram.isModified;
            var idx = document.title.indexOf("*");
            if (myDiagram.isModified) {
                if (idx < 0) document.title += "*";
            } else {
                if (idx >= 0) document.title = document.title.substr(0, idx);
            }
        });

        myDiagram.nodeTemplateMap.add("",
                $$(go.Node, "Auto",
                        { locationSpot: new go.Spot(0.5, 0.5), locationObjectName: "SHAPE", resizable: true, resizeObjectName: "SHAPE" },
                        new go.Binding("location", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
                        $$(go.Shape, "Cylinder1",
                                { name: "SHAPE",
                                    strokeWidth: 2,
                                    fill: $$(go.Brush, "Linear",
                                            { start: go.Spot.Left, end: go.Spot.Right,
                                                0: "gray", 0.5: "white", 1: "gray" }),
                                    minSize: new go.Size(100, 60),
                                    maxSize: new go.Size(100, 60),
                                    portId: "", fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides
                                },
                                new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify)),
                        $$(go.TextBlock,
                                { alignment: go.Spot.Center, textAlign: "center", margin: 5,
                                    editable: true },
                                new go.Binding("text","codeName").makeTwoWay())
                ));
        myDiagram.nodeTemplateMap.add("Process",
                $$(go.Node, "Auto",
                        { locationSpot: new go.Spot(0.5, 0.5), locationObjectName: "SHAPE", resizable: true, resizeObjectName: "SHAPE" },
                        new go.Binding("location", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
                        {},
                        $$(go.Shape, "Rectangle",
                                { name: "SHAPE",
                                    strokeWidth:.1,
                                    fill:"#363636",
                                    minSize: new go.Size(140, 80),
                                    maxSize: new go.Size(140, 80),
                                    portId: "", fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides
                                },
                                new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify)),
                        $$(go.TextBlock,
                                { alignment: go.Spot.Center, textAlign: "center",stroke:"rgb(255,255,255)", margin: 5,shadowVisible:true,
                                    editable: true },
                                new go.Binding("text").makeTwoWay())
                ));

        myDiagram.nodeTemplateMap.add("Start",
                $$(go.Node, "Auto", nodeStyle(),
                        new go.Binding("location", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
                        $$(go.Panel, "Auto",
                                $$(go.Shape, "Circle",
                                          { minSize: new go.Size(20, 20), fill: "#79C900", strokeWidth: 0 }),
                                $$(go.TextBlock, "Start", textStyle(),
                                        new go.Binding("text"))
                        ),
                        // three named ports, one on each side except the top, all output only:
                        makePort("L", go.Spot.Left, go.Spot.Left, true, false),
                        makePort("R", go.Spot.Right, go.Spot.Right, true, false),
                        makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
                ));

        myDiagram.nodeTemplateMap.add("End",
                $$(go.Node, "Auto", nodeStyle(),
                        new go.Binding("location", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
                        $$(go.Panel, "Auto",
                                $$(go.Shape, "Circle",
                                        { minSize: new go.Size(40, 40), fill: "#DC3C00", strokeWidth: 0 }),
                                $$(go.TextBlock, "End", textStyle(),
                                        new go.Binding("text"))
                        ),
                        // three named ports, one on each side except the bottom, all input only:
                        makePort("T", go.Spot.Top, go.Spot.Top, false, true),
                        makePort("L", go.Spot.Left, go.Spot.Left, false, true),
                        makePort("R", go.Spot.Right, go.Spot.Right, false, true)
                ));

        myDiagram.nodeTemplateMap.add("ExclusiveGateway",
                $$(go.Node, "Auto", nodeStyle(),
                        new go.Binding("location", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
                        $$(go.Shape,"Square",
                                { name: "SHAPE",
                                    geometryString: "F1 M0 0 L40 20 40 0 0 20z M20 10 L20 30 M12 30 L28 30",
                                    strokeWidth: 2,
                                    fill: $$(go.Brush, "Linear", { 0: "gray", 0.35: "white", 0.7: "gray" }),
                                    portId: "", fromSpot: new go.Spot(1, 0.35), toSpot: new go.Spot(0, 0.35) })
                ));
        myDiagram.nodeTemplateMap.add("ParallelGateway",
                $$(go.Node, "Auto", nodeStyle(),
                        new go.Binding("location", "pos", go.Point.parse).makeTwoWay(go.Point.stringify),
                        $$(go.Shape,"Square",
                                { name: "SHAPE",
                                    geometryString: "F1 M0 0 L40 20 40 0 0 20z M20 10 L20 30 M12 30 L28 30",
                                    strokeWidth: 2,
                                    fill: $$(go.Brush, "Linear", { 0: "gray", 0.35: "white", 0.7: "gray" }),
                                    portId: "", fromSpot: new go.Spot(1, 0.35), toSpot: new go.Spot(0, 0.35) })
                ));

        myDiagram.linkTemplate = $$(go.Link,
                        { routing: go.Link.AvoidsNodes, curve: go.Link.JumpOver, corner: 10, reshapable: true, toShortLength: 7 },
                        new go.Binding("points","points").makeTwoWay(),
                        // mark each Shape to get the link geometry with isPanelMain: true
                        $$(go.Shape, { isPanelMain: true, stroke: "black", strokeWidth: 5 }),
                        $$(go.Shape, { isPanelMain: true, stroke: "gray", strokeWidth: 3 }),
                        $$(go.Shape, { isPanelMain: true, stroke: "white", strokeWidth: 1, name: "PIPE", strokeDashArray: [10, 10] }),
                        $$(go.Shape, { toArrow: "Triangle", fill: "black", stroke: null })
                );

        // helper definitions for node templates
        function nodeStyle() {
            return [
                new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                {locationSpot: go.Spot.Center}
            ];
        }
        function textStyle() {
            return {
                font: "bold 11pt Helvetica, Arial, sans-serif",
                stroke: "whitesmoke"
            }
        }
        function makePort(name, align, spot, output, input) {
            var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
            // the port is basically just a transparent rectangle that stretches along the side of the node,
            // and becomes colored when the mouse passes over it
            return $$(go.Shape,
                    {
                        fill: "transparent",  // changed to a color in the mouseEnter event handler
                        strokeWidth: 0,  // no stroke
                        width: horizontal ? NaN : 4,  // if not stretching horizontally, just 8 wide
                        height: !horizontal ? NaN : 4,  // if not stretching vertically, just 8 tall
                        alignment: align,  // align the port on the main Shape
                        stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),
                        maxSize: new go.Size(60, 60),
                        portId: name,  // declare this object to be a "port"
                        fromSpot: spot,  // declare where links may connect at this port
                        fromLinkable: output,  // declare whether the user may draw links from here
                        toSpot: spot,  // declare where links may connect at this port
                        toLinkable: input,  // declare whether the user may draw links to here
                        cursor: "pointer",  // show a different cursor to indicate potential link point
                        mouseEnter: function(e, port) {  // the PORT argument will be this Shape
                            if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.5)";
                        },
                        mouseLeave: function(e, port) {
                            port.fill = "transparent";
                        }
                    });
        }

        loop();  // animate some flow through the pipes
    }


    function loop() {
        var diagram = myDiagram;
        setTimeout(function() {
            var oldskips = diagram.skipsUndoManager;
            diagram.skipsUndoManager = true;
            diagram.links.each(function(link) {
                var shape = link.findObject("PIPE");
                var off = shape.strokeDashOffset - 2;
                shape.strokeDashOffset = (off <= 0) ? 20 : off;
            });
            diagram.skipsUndoManager = oldskips;
            loop();
        }, 100);
    }

    function save(){
        var data = myDiagram.model.toJSON().replace("class","pos");
        var mask = $(".mask")[0];
        mask.classList.remove("hidden");
        $.ajax({
            url:'http://192.168.199.140:8080/neo4j/pos',
            type:"put",
            contentType:"application/json",
            data:data,
            success:function(res){
                mask.classList.add("hidden");
                if(res=="success"){
                    alert("OK");
                }
            }
        })
    }

    function load(da) {
        myDiagram.model = go.Model.fromJson(da);
    }

    $("#sample").on('click','[data-index]',function(e){
        var type = e.target.getAttribute("data-index");
        switch (type){
            case "big":{
                myDiagram.scale += 0.1;
            }
                break;
            case "small":{
                if(myDiagram.scale>0.2){
                    myDiagram.scale -= 0.1;
                }
            }
                break;
            case "save":{
                save();
            }
                break;
            default:
                break;
        }
    })

    var mask = $(".mask")[0];
    mask.classList.remove("hidden");
    $.getJSON("http://192.168.199.140:8080/neo4j/all",{},function(res){//http://192.168.199.140:8080/neo4j/all ./json/data.json
        mask.classList.add("hidden");
        if(res.pos){
            init(1);
        }else{
            init();
        }
        load(res)
    })

</script>
</body>
</html>
